package com.ecnu.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ecnu.common.config.RuoYiConfig;
import com.ecnu.common.constant.HttpStatus;
import com.ecnu.common.core.domain.AjaxResult;
import com.ecnu.common.core.domain.HttpCode;
import com.ecnu.common.core.domain.model.LoginUser;
import com.ecnu.common.core.page.PageDomain;
import com.ecnu.common.core.page.TableDataInfo;
import com.ecnu.common.enums.XCNKIType;
import com.ecnu.common.exception.ServiceException;
import com.ecnu.common.utils.OtherUtil;
import com.ecnu.common.utils.PageUtils;
import com.ecnu.common.utils.StringUtils;
import com.ecnu.common.utils.file.FileUploadUtils;
import com.ecnu.common.utils.http.HttpUtils;
import com.ecnu.common.utils.http.UrlUtils;
import com.ecnu.common.utils.ip.IpUtils;
import com.ecnu.common.utils.uuid.IdUtils;
import com.ecnu.system.domain.IncubationFile;
import com.ecnu.system.domain.SoftwareTool;
import com.ecnu.system.domain.SoftwareUser;
import com.ecnu.system.domain.dto.EvaluateListDTO;
import com.ecnu.system.domain.dto.SoftwareDTO;
import com.ecnu.system.domain.vo.Incubation.FactoryPageVO;
import com.ecnu.system.domain.vo.SoftwareToolVO;
import com.ecnu.system.mapper.SoftwareToolMapper;
import com.ecnu.system.mapper.SoftwareUserMapper;
import com.ecnu.system.service.ISoftwareToolService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

import static com.ecnu.common.utils.OtherUtil.getImageExtension;
import static com.ecnu.common.utils.OtherUtil.parseBase64Image;

@Service
public class SoftwareToolServiceImpl extends ServiceImpl<SoftwareToolMapper, SoftwareTool> implements ISoftwareToolService {
    @Autowired
    private SoftwareToolMapper softwareToolMapper;
    @Autowired
    private SoftwareUserMapper softwareUserMapper;

    protected String getId() {
        return IdUtils.fastSimpleUUID();
    }
    protected void startPage(PageDomain pageDomain) {
        PageUtils.startPage(pageDomain);
    }

    @Override
    public TableDataInfo getList(EvaluateListDTO dto, LoginUser loginUser) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        LambdaQueryWrapper<SoftwareTool> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(dto.getTitle())) {
            wrapper.like(SoftwareTool::getName, dto.getTitle());
        }
        wrapper.eq(SoftwareTool::getDelFlag, "0");
        startPage(dto.getPageDomain());
        List<SoftwareTool> softwareTools = softwareToolMapper.selectList(wrapper);
        List<SoftwareToolVO> copy = new ArrayList<>();
        softwareTools.forEach(softwareTool -> {
            SoftwareToolVO softwareToolVO = new SoftwareToolVO();
            BeanUtils.copyProperties(softwareTool, softwareToolVO);
            softwareToolVO.setId(String.valueOf(softwareTool.getId()));

            // 转换图片二进制数据为Base64
//            if (softwareTool.getImageData() != null) {
//                String base64Image = softwareTool.getImageData();
//                softwareToolVO.setImageBase64(base64Image);
//            }

            copy.add(softwareToolVO);
        });
        return OtherUtil.tableSuccess(copy);
    }

    @Override
    public AjaxResult edit(SoftwareDTO dto, LoginUser loginUser) {
        SoftwareTool tool = new SoftwareTool();
        BeanUtils.copyProperties(dto, tool);

        // 处理图片Base64数据
        if (StringUtils.isNotBlank(dto.getImageBase64())) {
            try {
                //调整--图片的base64转换为file文件存储到本地，然后相对地址存储到数据库中
                String base64Str = dto.getImageBase64();

                // 1. 提取纯 Base64 数据 + 推断 MIME 类型
                OtherUtil.Base64ImageInfo imageInfo = parseBase64Image(base64Str);
                if (imageInfo == null || imageInfo.getData() == null || imageInfo.getData().length == 0) {
                    return AjaxResult.error("图片格式错误");
                }

                // 2. 生成安全文件名（带真实扩展名）
                String ext = getImageExtension(imageInfo.getMimeType());
                String fileName = "software_" + getId() + "." + ext;

                // 3. 上传文件（写入磁盘）
                String uploadPath = RuoYiConfig.getUploadPath();
                String relativePath = FileUploadUtils.upload(uploadPath, fileName, imageInfo.getData());

                tool.setImageData(relativePath);
                tool.setPictureUrl(relativePath);
            } catch (IllegalArgumentException e) {
                log.warn ("非法的 Base64 数据格式");
                return AjaxResult.error("图片格式错误");
            } catch (IOException e) {
                log.error("文件上传过程中发生 IO 错误", e);
                return AjaxResult.error("服务器内部错误，请稍后再试");
            } catch (Exception e) {
                log.error("图片Base64解码失败", e);
                return AjaxResult.error("图片格式错误");
            }
        }

        Boolean status = null;
        if (StringUtils.isBlank(dto.getId())) {
            status = save(tool);
        } else  {
            tool.setId(Integer.valueOf(dto.getId()));
            status = updateById(tool);
        }
        return status ? AjaxResult.success("保存成功") : AjaxResult.error("保存失败");
    }

    @Override
    public TableDataInfo getListForUser(EvaluateListDTO dto, LoginUser loginUser) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        LambdaQueryWrapper<SoftwareTool> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(dto.getTitle())) {
            wrapper.like(SoftwareTool::getName, dto.getTitle());
        }
        wrapper.eq(SoftwareTool::getDelFlag, "0");
        wrapper.eq(SoftwareTool::getStatus, "1");
        startPage(dto.getPageDomain());
        List<SoftwareTool> softwareTools = softwareToolMapper.selectList(wrapper);
        Map<Integer, List<SoftwareUser>> hashMap = new HashMap<>();
        //**新增：查询用户授权工具 20251029
        if (CollectionUtils.isNotEmpty(softwareTools)&&loginUser.getUserId()!= null) {
            List<Integer> collect = softwareTools.stream().map(SoftwareTool::getId).collect(Collectors.toList());
            LambdaQueryWrapper<SoftwareUser> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SoftwareUser::getUserId, loginUser.getUserId())
                    .eq(SoftwareUser::getDelFlag, "0")
                    .in(SoftwareUser::getSoftwareId, collect);
            List<SoftwareUser> softwareUsers = softwareUserMapper.selectList(queryWrapper);
            hashMap = softwareUsers.stream()
                    .collect(Collectors.groupingBy(SoftwareUser::getSoftwareId));
        }

        //**********
        List<SoftwareToolVO> copy = new ArrayList<>();
        Map<Integer, List<SoftwareUser>> finalHashMap = hashMap;
        softwareTools.forEach(softwareTool -> {
            SoftwareToolVO softwareToolVO = new SoftwareToolVO();
            BeanUtils.copyProperties(softwareTool, softwareToolVO);
            softwareToolVO.setId(String.valueOf(softwareTool.getId()));
//            softwareToolVO.getImageData(softwareTool.getImageData());

            // 处理cnki接口
            if (softwareTool.getUrl().contains("//x.cnki.net")&&loginUser.getUserId()!= null) {//现阶段调整cnki研学的接口
                try {
                    XCnki(softwareToolVO,loginUser);
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
            }else if (softwareTool.getUrl().contains("/jupyter/")&&loginUser.getUserId()!= null){
                Jupyter(softwareToolVO,loginUser);

            }
            //处理授权逻辑、连接类型逻辑  ***新加 20251029
//            String authStatus = "1";  // 默认未授权
//            String isContent = softwareToolVO.getIsContent().equals("0") ? "0" : "1";  // 默认无内容访问权限

            String authStatus = "2";  // 默认未授权
            String isContent = softwareToolVO.getIsContent().equals("0") ? "0" : "2";  // 默认无内容访问权限
            if (loginUser.getUserId() != null) {
                List<SoftwareUser> softwareUsers = finalHashMap.get(softwareTool.getId());
                if (CollectionUtils.isNotEmpty(softwareUsers)) {
                    authStatus = "1";  // 已授权
                    isContent = softwareToolVO.getIsContent().equals("0") ? "0" : "1";  // 有内容访问权限
                }
            }

            softwareToolVO.setAuthStatus(authStatus);
            softwareToolVO.setIsContent(isContent);

            copy.add(softwareToolVO);
        });
        return OtherUtil.tableSuccess(copy);
    }

    private void Jupyter(SoftwareToolVO softwareToolVO, LoginUser loginUser) {
        String s = softwareToolVO.getUrl() + "?user=" + loginUser.getUserId();
        softwareToolVO.setUrl(s);
    }

    private void XCnki(SoftwareToolVO softwareTool, LoginUser loginUser) throws UnsupportedEncodingException {
        String strings = softwareToolMapper.selectMenu_("116");//获取软件工具菜单的相对地址
        if (StringUtils.isNotBlank(strings)) {
            String extracted = extracted(softwareTool.getUrl(), loginUser.getUserId(), strings);//后续改成工具地址
            softwareTool.setUrl(extracted);
        }
    }
    public String extracted(String title, Long userId, String targetUrl) throws UnsupportedEncodingException {

        //取token
        String url = "https://my.cnki.net/IntegrateLogin/api/IntegrateLoginApi/UserLogin";
        String ipAddr = IpUtils.getIpAddr();
        //包装参数
        HashMap<String, String> map = new HashMap<>();
        map.put(XCNKIType.Key.getCode(), XCNKIType.Key.getInfo());//学校秘钥
        map.put(XCNKIType.UserName.getCode(), XCNKIType.UserName.getInfo());//学校名称
        map.put("SubUserName", String.valueOf(userId));//登录用户id
        map.put("UserIp", ipAddr);//用户客户端ip
        String jsonString = JSON.toJSONString(map);
        String contentType = "application/json";
        //获取token
        String token = HttpUtils.sendPost(url, jsonString, contentType,new HashMap<>());
        if (StringUtils.isBlank(token)) {
            return title;
        }
        HttpCode httpCode = JSON.parseObject(token, HttpCode.class);
        if (httpCode.getCode().equals("0")) {
            log.error("知网研学获取token失败:"+httpCode.getMessage());
            return title;
        }
        //获取aamsApi的jwt
        String jwt = OtherUtil.getJwt(ipAddr);
        //读取用户信息
        String xcnkiUser =OtherUtil.selectXCNKIUser(jwt, httpCode.getToken());
        //用户未绑定的情况跳转登录地址设为学习中心平台
        if (StringUtils.isBlank(xcnkiUser)) {
            title="https://ba.ecnu.edu.cn"+targetUrl+"/list";
        }else {
            //有对接上的话添加团队
            OtherUtil.InstantTeam(xcnkiUser, jwt);
        }
        String geturl="https://my.cnki.net/IntegrateLogin/Redirect/Index?token="+httpCode.getToken()
                +"&SubUserName="+userId+"&ReturnUrl="+ URLEncoder.encode(title,"UTF-8");

        return geturl;
    }
}
